package com.epam.Client;

import java.util.Random;

import org.apache.log4j.Logger;

import com.epam.Bank.Account;
import com.epam.Bank.Bank;
import com.epam.Bank.Cashier;
import com.epam.Bank.Observer;
import com.epam.Bank.Bank.Currency;
import com.epam.Runner.Main;

public class Client implements Runnable {

	Random rand = new Random();
	private int clientCashUSD;
	private int clientCashEuro;
	private int accountNumber;

	private static final Logger log = Logger.getLogger(Client.class);

	public Client() {

	}

	public Client(int accountNumber) throws Exception {
		this.clientCashUSD = rand.nextInt(2000);
		this.clientCashEuro = rand.nextInt(2000);
		this.accountNumber = createAccount(accountNumber);
	}

	public Client(int cashUSD, int cashEuro, int accountNumber)
			throws Exception {
		this.clientCashUSD = cashUSD;
		this.clientCashEuro = cashEuro;
		this.accountNumber = createAccount(accountNumber);
	}

	public int createAccount(int accountNumber) throws Exception {
		if (Bank.checkAccountNumbers(accountNumber)) {
			throw new Exception("Account number is not available");
		} else {
			new Account(accountNumber);
		}
		return accountNumber;
	}

	public int getClientCashUSD() {
		return clientCashUSD;
	}

	public void setClientCashUSD(int cash) {
		this.clientCashUSD = cash;
	}

	public int getClientCashEuro() {
		return clientCashEuro;
	}

	public void setClientCashEuro(int clientCashEuro) {
		this.clientCashEuro = clientCashEuro;
	}

	public int getAccountNumber() {
		return this.accountNumber;
	}

	public int getAccountBalanceUSD() {
		return Bank.getAccountMap().get(this.accountNumber)
				.getAccountBalanceUSD();
	}

	public int getAccountBalanceEuro() {
		return Bank.getAccountMap().get(this.accountNumber)
				.getAccountBalanceEuro();
	}

	private static Random random = new Random();

	public static int randomNumber(int n) {
		synchronized (random) { // synchronize
			return random.nextInt(n);
		}
	}

	public void run() {
		while (Main.getClients().size() > 0) {
			Cashier c = Bank.getCashier();
			log.info("Cashier occupied");
			switch (randomNumber(3)) {
			case 0:
				c.deposit(Main.getClient(), Currency.USD, randomNumber(500) + 1);
				break;
			case 1:
				c.exchange(Main.getClient(), Currency.USD, Currency.Euro,
						randomNumber(1000) + 1);
				break;
			case 2:
				c.deposit(Main.getClient(), Currency.Euro,
						randomNumber(780) + 1);
				break;
			}
			if (Bank.checkCashOverflow(c)) {
				Observer o = Bank.getObservers();
				Bank.collectMoney(c);
				Bank.setObservers(o);
			}
			try {
				Thread.sleep(randomNumber(2000));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Bank.setCashier(c);

		}
	}
}
